package com.tqz.zookeeper.rawapi.configcenter;

import cn.hutool.json.JSONUtil;
import com.tqz.zookeeper.common.ZookeeperUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.TimeUnit;

/**
 * 使用zk实现配置中心的功能，监听配置节点的变化.
 *
 * @author <a href="https://github.com/tian-qingzhao">tianqingzhao</a>
 * @since 2025/9/4 20:50
 */
@Slf4j
public class ConfigCenterTest {

    public static void main(String[] args) throws InterruptedException, KeeperException {
        ZooKeeper zooKeeper = ZookeeperUtil.create();

        Config config = new Config();
        config.setKey("server.port");
        config.setValue("8080");

        String path = "/config-service";

        Stat existsStat = zooKeeper.exists(path, null);
        if (existsStat == null) {
            zooKeeper.create(path,
                    JSONUtil.toJsonStr(config).getBytes(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE,
                    CreateMode.PERSISTENT);
        }

        Watcher watcher = new Watcher() {
            @SneakyThrows
            @Override
            public void process(WatchedEvent event) {
                if (event.getType() == Event.EventType.NodeDataChanged
                        && event.getPath() != null && path.equals(event.getPath())) {
                    log.info(" PATH:{}  发生了数据变化", event.getPath());
                    //获取配置信息
                    byte[] data = zooKeeper.getData(path, this, null);
                    Config config = JSONUtil.toBean(new String(data), Config.class);
                    log.info("数据发生变化: {}", config);
                }
            }
        };

        byte[] data = zooKeeper.getData(path, watcher, null);
        Config originalMyConfig = JSONUtil.toBean(new String(data), Config.class);
        log.info("原始数据: {}", originalMyConfig);

        TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    private static class Config {

        private String key;

        private String value;

    }
}


